﻿HmJS.$Import('log');
HmJS.$Import('lang.class');
HmJS.$Import('math.Number3D');
HmJS.$Import('core.more');

HmJS.register('demo.module.lang.class.interface', function ($ns) {
	var that = {};

	/* THIS IS AN EXAMPLE */

	var Number3D = $ns.math.Number3D;

	/* Interface ITypeIdentifyable */
	var ITest = new Interface("ITest", {
		Name: String
	});

	/* Interface ITypeIdentifyable */
	var ITypeIdentifyable = new Interface("ITypeIdentifyable", {
		Type: Number3D
	});

	/* Interface INotifyPropertyChanged */
	var INotifyPropertyChanged = new Interface("INotifyPropertyChanged", {
		Interfaces: [ITypeIdentifyable], /* This wouldn't be needed for an INotifyPropertyChanged Interface */
		NotifyPropertyChanged: function () { },
		Set: function (a, b) { }
	});

	/* Interface ICloneable */
	var ICloneable = that.ICloneable = new Interface("IClonable", {
		Clone: Function
	});

	/* Interface IConvertible */
	var IConvertible = new Interface("IConvertible", {
		ToString: Function
	});

	/* A sample Class wich implements some Intefaces */
	var NotifyPropertyChanged = that.NotifyPropertyChanged = new Class({
		Implements: Events,
		Interfaces: [INotifyPropertyChanged, ITypeIdentifyable, ICloneable, IConvertible],

		/* #region ITypeIdentifyable Members */
		Type: new Number3D(2, 2, 2),
		/* #endregion */

		/* #region INotifyPropertyChanged Members */
		NotifyPropertyChanged: function (pName, pValue) {
			this.fireEvent('propertyChanged', { sender: this, property: pName, value: pValue });
		},
		Set: function (pName, pValue) {
			try {
				if (pName in this) {
					this[pName] = pValue;
					this.NotifyPropertyChanged(pName, pValue);
				}
				else {
					throw new ReferenceError(pName + " does not exist");
				}
			}
			catch (error) {
				try {
					log.error(error);
				}
				catch (e) {
					log.error(error);
				}
			}
		},
		/* #endregion */

		/* #region IClonable Members */
		Clone: function () {
			var obj = new Class();

			for (p in this) {
				obj[p] = this[p];
			}
			return obj;
		},
		/* #endregion */

		/* #region IConvertible Members */
		ToString: function () {
			return this.Type;
		}
		/* #endregion */
	});

	that.black = new Color('#000');
	log.info('type Of black: ' + typeOf(that.black));

	log.info('type Of ICloneable: ' + typeOf(ICloneable));


	var Animal = new Class({
		initialize: function (age) {
			this.age = age;
		}
	});
	var Cat = new Class({
		Extends: Animal,
		initialize: function (name, age) {
			this.parent(age); // calls initalize method of Animal class
			this.name = name;
		}
	});
	var myCat = that.myCat = new Cat('Micia', 20);
	log.info('myCat是否是接口ITest的实例: ' + interfaceOf(myCat, ITest));


	that.todo = function () {
		var c = new NotifyPropertyChanged();
		that.num3d = c.Type;
		log.info('Number3D实例: ' + c.Type);
		log.info('c是否是接口ICloneable的实例: ' + interfaceOf(c, ICloneable));
		log.info('c是否是接口ITypeIdentifyable的实例: ' + interfaceOf(c, ITypeIdentifyable));
		log.info('c是否是接口ITest的实例: ' + interfaceOf(c, ITest));
	}

	return that;
});
